package com.hdd.biz.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hdd.biz.app.dto.*;
import com.hdd.biz.app.entity.*;
import com.hdd.biz.app.mapper.APPMemberMapper;
import com.hdd.biz.app.mapper.APPPaintingWorksMapper;
import com.hdd.biz.app.service.HomeService;
import com.hdd.biz.app.service.PublishService;
import com.hdd.biz.finance.service.PaymetService;
import com.hdd.biz.member.entity.Member;
import com.hdd.biz.member.service.MemberService;
import com.hdd.biz.operate.entity.Complaints;
import com.hdd.biz.operate.entity.Dict;
import com.hdd.biz.operate.entity.Feedback;
import com.hdd.biz.operate.service.ComplaintsService;
import com.hdd.biz.operate.service.DictService;
import com.hdd.biz.operate.service.FeedbackService;
import com.hdd.biz.painting.entity.PaintingTopic;
import com.hdd.biz.painting.entity.PaintingWorks;
import com.hdd.biz.painting.entity.UserFollow;
import com.hdd.biz.painting.mapper.PaintingTopicMapper;
import com.hdd.biz.painting.service.FavourService;
import com.hdd.biz.painting.service.PaintingTopicLinkService;
import com.hdd.biz.painting.service.UserFollowService;
import com.hdd.utils.ImageUtil;
import com.hdd.utils.wx.RedisUtil;
import com.hdd.utils.wx.WxMiniProgramUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
@Slf4j
public class HomeServiceImpl implements HomeService {

    @Autowired
    private FavourService favourService;
    @Autowired
    private APPPaintingWorksMapper appPaintingWorksMapper;
    @Autowired
    private UserFollowService userFollowService;
    @Autowired
    private PublishService publishService;
    @Autowired
    private APPMemberMapper appMemberMapper;
    @Autowired
    private ComplaintsService complaintsService;
    @Autowired
    private FeedbackService feedbackService;
    @Autowired
    private DictService dictService;
    @Autowired
    private PaymetService paymetService;
    @Autowired
    private WxMiniProgramUtil wxMiniProgramUtil;
    @Autowired
    private PaintingTopicMapper topicMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private PaintingTopicLinkService linkService;
    @Autowired
    private MemberService memberService;
    @Override
    public AppResponse worksInfo(WorksInfoRequest request) {
        AppResponse response = new AppResponse();

        QueryWrapper<PaintingWorks> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",request.getWorksId());
        PaintingWorks paintingWorks = appPaintingWorksMapper.selectOne(queryWrapper);
        if(paintingWorks==null){
            response.setCode(-1000);
            response.setMessage("该作品不存在或已下架");
            return response;
        }
        response.setItem(convertWork(paintingWorks,request.getUserId()));
        return response;
    }

    @Override
    public AppResponse followList(RecommendRequest request) {
        AppResponse response = new AppResponse();
        if(request.getPageNo()<1){
            response.setCode(1000);
            response.setMessage("pageNo必须大于0");
            return response;
        }

        Map<String,Object> map = new HashMap<>();
        map.put("pageNo",(request.getPageNo()-1)*request.getPageSize());
        map.put("pageSize",request.getPageSize());
        map.put("userId",request.getUserId());
        List<PaintingWorks> works = appPaintingWorksMapper.followList(map);
        response.setItems(convertWorks(works,request.getUserId()));
        return response;
    }


    @Override
    public AppResponse worksDetailsList(WorksInfoRequest request) {
        AppResponse response = new AppResponse();
        Map<String,Object> map = new HashMap<>();
        map.put("pageNo",(request.getPageNo()-1)*request.getPageSize());
        map.put("pageSize",request.getPageSize());
        map.put("userId",request.getAuthorId());
        map.put("wiki_id",request.getType());

        List<PaintingWorks> works = appPaintingWorksMapper.worksDetailsList(map);
        List<PaintingWorksModel> list = convertWorks(works,request.getUserId());
        PaintingWorksModel model = null;
        if(!StringUtils.isEmpty(request.getWorksId())){
            PaintingWorks paintingWorks = appPaintingWorksMapper.worksDetails(request.getWorksId());
            if(paintingWorks!=null){
                model = convertWork(paintingWorks,request.getUserId());
                for(int i=0;i<list.size();i++){
                    if(list.get(i).getId().equals(request.getWorksId())){
                        list.remove(i);
                    }
                }
                list.add(0,model);
            }

        }

        for(int i=0;i<list.size();i++){
            if(redisUtil.hasKey("paymentAmount:"+list.get(i).getId())){
                list.get(i).setAmount(redisUtil.get("paymentAmount:"+list.get(i).getId()).toString());
            }else{
                list.get(i).setAmount("0");
            }
        }

        response.setItems(list);
        return response;
    }

    @Override
    public AppResponse recommend(RecommendRequest request) {
        AppResponse response = new AppResponse();
        if(request.getPageNo()<1){
            response.setCode(1000);
            response.setMessage("pageNo必须大于0");
            return response;
        }

          Map<String,Object> map = new HashMap<>();
//        map.put("pageNo",(request.getPageNo()-1)*request.getPageSize());
//        map.put("pageSize",request.getPageSize());
//        List<PaintingWorks> works = appPaintingWorksMapper.recommend(map);
//        response.setItems(convertWorks(works,request.getUserId()));
//
//

        List<PaintingWorks> worksList = new ArrayList<>();
        if(request.getPageNo()<=1){
            //随机推荐 3
            map.put("limit",3);
            List<PaintingWorks>  randList =  appPaintingWorksMapper.recommendRand(map);
            worksList.addAll(randList);

            //置顶推荐 3
            List<String> list = new ArrayList<>();
            for(int i=0;i<randList.size();i++){
                list.add(randList.get(i).getId());
            }
            QueryWrapper<PaintingWorks> wrapper = new QueryWrapper<>();
            wrapper.eq("istop","T");
            wrapper.eq("del_flag",0);
            wrapper.eq("shows",2);
            wrapper.eq("recommend",1);
            wrapper.notIn("id",list);
            wrapper.last(" limit 3");
            //最新推荐 5
            List<PaintingWorks>  top =  appPaintingWorksMapper.selectList(wrapper);
            worksList.addAll(top);
        }

        QueryWrapper<PaintingWorks> wrapper2 = new QueryWrapper<>();
        Page<PaintingWorks> pages = new Page<>(request.getPageNo(),request.getPageSize());
        wrapper2.eq("del_flag",0);
        wrapper2.eq("shows",2);
        wrapper2.eq("istop","F");
        wrapper2.eq("shows",2);
        wrapper2.eq("recommend",1);
        wrapper2.orderByDesc("create_time");
        IPage<PaintingWorks> mapIPage = appPaintingWorksMapper.selectPage(pages, wrapper2);
        worksList.addAll(mapIPage.getRecords());
        response.setItems(convertWorks(worksList,request.getUserId()));
        return response;
    }

    @Override
    public AppResponse follow(WorksInfoRequest request) {
        AppResponse response = new AppResponse();
        if(favourService.isFavour(request.getUserId(),request.getWorksId())){
            favourService.delFavour(request.getUserId(), request.getWorksId());
            response.setMessage("已取消关注");
            appPaintingWorksMapper.reduceFavourCount(request.getWorksId());

        }else {
            favourService.insertFavour(request.getUserId(), request.getWorksId());
            response.setMessage("关注成功");
            appPaintingWorksMapper.addFavourCount(request.getWorksId());
        }
        return response;
    }


    @Override
    public AppResponse amountRest(WorksInfoRequest request) {
        AppResponse response = new AppResponse();
        redisUtil.del("paymentAmount:"+request.getWorksId());
        return response;
    }

    @Override
    public AppResponse give(WorksInfoRequest request) {
        AppResponse response = new AppResponse();


        return response;
    }

    @Override
    public AppResponse reward(RewardRequest request) {
        return null;
    }

    @Override
    public AppResponse addvisit(WorksInfoRequest request) {
        AppResponse response = new AppResponse();
        appPaintingWorksMapper.addvisit(request.getWorksId());
        QueryWrapper<PaintingWorks> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",request.getWorksId());
        PaintingWorks paintingWorks = appPaintingWorksMapper.selectOne(queryWrapper);
        if(paintingWorks!=null){
            response.setItem(paintingWorks.getVisitCount());
        }
        return response;
    }

    /**
     * 作品对象转换
     * @param works
     * @return
     */
    public List<PaintingWorksModel> convertWorks(List<PaintingWorks> works,String userId){
        List<PaintingWorksModel> list = new ArrayList<>();
        PaintingWorksModel worksModel = null;
        Member member = null;
        for(PaintingWorks p:works){
            worksModel = new PaintingWorksModel();
            worksModel.setId(p.getId());
            worksModel.setUserId(p.getUserId());
            worksModel.setPainting(p.getPainting());
            worksModel.setPaintingNo(p.getPaintingNo());
            worksModel.setPaintingName(p.getPaintingName());
            worksModel.setVisitCount(p.getVisitCount());
            worksModel.setPraiseCount(p.getVisitCount());
            worksModel.setPaintingDescription(p.getPaintingDescription());
            worksModel.setRewardCount(p.getRewardCount());
            worksModel.setFavourCount(p.getFavourCount());
            worksModel.setReshipmentCount(p.getReshipmentCount());
            worksModel.setAllowReward(p.getAllowReward());
            worksModel.setShareCount(p.getShareCount());
            worksModel.setWikiId(p.getWikiId());
            worksModel.setMediaTime(p.getMediaTime());
            worksModel.setMediaUrl(p.getMediaUrl());
            worksModel.setTopics(publishService.getTopicsByWorkId(p.getId()));
            if(!StringUtils.isEmpty(userId)){
                worksModel.setUserFollow(userFollowService.isFollow(userId,p.getUserId()));
                worksModel.setFollow(favourService.isFavour(userId,p.getId()));
            }

            member = memberService.findMemberByUid(p.getUserId());
            if(member!=null){
                worksModel.setNickName(member.getNickname());
                worksModel.setHeadImgUrl(member.getHeadImgUrl());
            }

            list.add(worksModel);
        }
        return list;
    }


    /**
     * 作品对象转换
     * @param p
     * @return
     */
    public PaintingWorksModel convertWork(PaintingWorks p,String userId){
        PaintingWorksModel worksModel = new PaintingWorksModel();
            worksModel.setId(p.getId());
            worksModel.setUserId(p.getUserId());
            worksModel.setPainting(p.getPainting());
            worksModel.setPaintingNo(p.getPaintingNo());
            worksModel.setPaintingName(p.getPaintingName());
            worksModel.setVisitCount(p.getVisitCount());
            worksModel.setPraiseCount(p.getVisitCount());
            worksModel.setAllowReward(p.getAllowReward());
            worksModel.setRewardCount(p.getRewardCount());
            worksModel.setDraftInfo(p.getDraftInfo());
            worksModel.setMediaTime(p.getMediaTime());
            worksModel.setFavourCount(p.getFavourCount());
            worksModel.setReshipmentCount(p.getReshipmentCount());
            worksModel.setPaintingDescription(p.getPaintingDescription());
            worksModel.setShareCount(p.getShareCount());
            worksModel.setNickName(p.getNickName());
            worksModel.setWikiId(p.getWikiId());
            worksModel.setHeadImgUrl(p.getHeadImgUrl());
            worksModel.setMediaUrl(p.getMediaUrl());
            worksModel.setTopics(publishService.getTopicsByWorkId(p.getId()));
             if(!StringUtils.isEmpty(userId)){
               worksModel.setUserFollow(userFollowService.isFollow(userId,p.getUserId()));
               worksModel.setFollow(favourService.isFavour(userId,p.getId()));
           }
        return worksModel;
    }


    @Override
    public AppResponse followUser(WorksInfoRequest request) {
        AppResponse response = new AppResponse();
        Lock lock = new ReentrantLock(true);
        Integer nums = 0;
        try {
            lock.lock();
            nums = userFollowService.find(request.getUserId(),request.getAuthorId());
            log.info("nums:------"+nums);
            if(nums<1){
                //判断是不是第一次关注 是的话关注自己
                if(userFollowService.find(request.getUserId(),request.getUserId())<1){
                    userFollowService.insert(request.getUserId(),request.getUserId());
                }
                userFollowService.insert(request.getUserId(),request.getAuthorId());
                redisUtil.incr("followUser:"+request.getAuthorId(),1);
                response.setMessage("关注成功");
                return response;
            }
        }finally {
            lock.unlock();
        }


        response.setMessage("关注失败");
        response.setCode(-1000);
        return response;
    }


    @Override
    public AppResponse suggestedFollows(AppRequest request) {
        AppResponse res = new AppResponse();
        //TODO 推荐关注
        Map<String,Object> map = new HashMap<>();
        map.put("limit",5);
        if(!StringUtils.isEmpty(request.getUserId())){
            map.put("user_id",request.getUserId());
        }
        List<Member> members =  appMemberMapper.randMember(map);
        for(int i=0;i<members.size();i++){
            members.get(i).setPaintingWorksModelList(appPaintingWorksMapper.findWorksByUserId(members.get(i).getUserId()));
        }
        res.setItems(convertMember(members));
        return res;
    }


    public List<UserCenterModel> convertMember(List<Member> list){
        List<UserCenterModel> userCenterModels = new ArrayList<>();
        UserCenterModel userCenterModel = null;
        for(int i=0;i<list.size();i++){
            userCenterModel = new UserCenterModel();
            userCenterModel.setUserId(list.get(i).getUserId());
            userCenterModel.setNick(list.get(i).getNickname());
            userCenterModel.setHeadImgUrl(list.get(i).getHeadImgUrl());
            userCenterModel.setDescription(list.get(i).getDescription());
            userCenterModel.setWorksList(list.get(i).getPaintingWorksModelList());
            userCenterModels.add(userCenterModel);
        }
        return userCenterModels;
    }


    @Override
    public AppResponse complaint(ComplaintRequest request) {
        AppResponse res = new AppResponse();
        Complaints complaints = new Complaints();
        complaints.setUserId(request.getUserId());
        complaints.setImgUrl(request.getImage());
        complaints.setReason(request.getReason());
        complaints.setPaintingId(request.getWorksId());
        complaints.setDescription(request.getDescribe());
        complaintsService.createComplaints(complaints);
        return res;
    }


    @Override
    public AppResponse feedback(FeedbackRequest request) {
        AppResponse res = new AppResponse();
        Feedback feedback = new Feedback();
        feedback.setUserId(request.getUserId());
        feedback.setDescription(request.getDescription());
        feedback.setImgUrl(request.getImgUrl());
        feedback.setContactWay(request.getContactWay());
        feedback.setStatus(0);
        feedbackService.save(feedback);
        return res;
    }

    @Override
    public AppResponse cancelFollow(WorksInfoRequest request) {
        AppResponse res = new AppResponse();
        userFollowService.cancelFollow(request.getUserId(),request.getAuthorId());

        if(redisUtil.hasKey("followUser:"+request.getAuthorId())){
            Integer l = Integer.parseInt(redisUtil.get("followUser:"+request.getAuthorId()).toString());
            if(l>0){
                redisUtil.set("followUser:"+request.getAuthorId(),l-1);
            }
        }
        return res;
    }


    @Override
    public AppResponse rewardConfigure(AppRequest request) {
        AppResponse response = new AppResponse();
        Dict dict =  dictService.findDictByName("REWARD");
        RewardConfigureModel model = new RewardConfigureModel();
        if(dict==null){
            response.setCode(-1000);
            response.setMessage("读取配置失败");
            return response;
        }
        model.setExample(dict.getDictValue());
        model.setLimit(dict.getDictValue2());
        response.setItem(model);
        return response;
    }


    @Override
    public AppResponse rewardRecord(RewardRecordRequest request) {
        AppResponse response = new AppResponse();
        List<RewardRecordModel> list = paymetService.rewardRecord(request.getWorksId(),request.getPageNo(),request.getPageSize());
        Dict dict = dictService.findDictByName("DEFAULTAVATAR");
        for(int i =0;i<list.size();i++){
            if("T".equals(list.get(i).getAnonymity())){
                list.get(i).setHeadUrl(dict.getDictValue());
            }
        }
        response.setItems(list);
        response.setItem(paymetService.rewardCount(request.getWorksId()));
        return response;
    }

    @Override
    public AppResponse getPoster(WorksInfoRequest request) {
        AppResponse response = new AppResponse();

        PaintingWorks paintingWorks = appPaintingWorksMapper.selectById(request.getWorksId());
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("user_id",paintingWorks.getUserId());
        Member member =  appMemberMapper.selectOne(wrapper);
        String backgroundImageUrl = "https://qiniu.17huaduoduo.com/hdd_bg.png";
        String zp=paintingWorks.getPainting();
        String headUrl = member.getHeadImgUrl();
        String nameText =member.getNickname();
        String cqText = "扫一扫，为我加油！";
        byte[] bytes = wxMiniProgramUtil.getUnlimited("targetId=" + paintingWorks.getUserId()+"&worksId="+request.getWorksId()+"&from=share", "/pages/mine/paintList");
        String url = "-1";
        try {
            url =  ImageUtil.drawImage(backgroundImageUrl,bytes, headUrl, nameText, cqText,zp);
        }catch (Exception e){
            e.printStackTrace();
        }
        response.setItem(url);
        return response;
    }



    @Override
    public AppResponse topicWorks(TopicsRequest request) {
        AppResponse response = new AppResponse();
        PaintingTopic paintingTopic =  topicMapper.selectById(request.getId());
        TopicWorksModel topicWorksModel = new TopicWorksModel();
        topicWorksModel.setVisit(appPaintingWorksMapper.totalVisit(request.getId()));
        topicWorksModel.setWorks(appPaintingWorksMapper.totalWorks(request.getId()));
        topicWorksModel.setName(paintingTopic.getName());
        topicWorksModel.setTitle(paintingTopic.getRemarks());
        topicWorksModel.setId(request.getId());
        List<String> ids = new ArrayList<>();
        ids.add(request.getId()+"");
        QueryWrapper<PaintingWorks> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag",0);
        wrapper.eq("shows",2);
//        if("T".equals(request.getIsWiki())){
//            wrapper.eq("wiki_id",3);
//        }else{
//            wrapper.lt("wiki_id",3);
//        }

        wrapper.in("id",linkService.getWorksId(request.getId().toString()));
        wrapper.orderByDesc("create_time");
        List<PaintingWorks> works = appPaintingWorksMapper.selectList(wrapper);
        if(!StringUtils.isEmpty(paintingTopic.getPictureUrl())){
            topicWorksModel.setImage(paintingTopic.getPictureUrl());
        }else{
            if(!works.isEmpty()){
                topicWorksModel.setImage(works.get(0).getPainting());
            }
        }
        topicWorksModel.setList(convertWorks(works));
        response.setItem(topicWorksModel);
        return response;
    }


    @Override
    public AppResponse topicWorksDetailsList(TopicsRequest request) {
        AppResponse response = new AppResponse();
        List<String> strings = linkService.getWorksId(request.getId().toString(),request.getPageNo(),request.getPageSize());
        QueryWrapper<PaintingWorks> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag",0);
        wrapper.eq("shows",2);
        wrapper.in("id",strings);
//        if("T".equals(request.getIsWiki())){
//            wrapper.eq("wiki_id",3);
//        }else{
//            wrapper.lt("wiki_id",3);
//        }

        wrapper.orderByDesc("create_time");
        List<PaintingWorks> works = appPaintingWorksMapper.selectList(wrapper);
        List<PaintingWorksModel> list = convertWorks(works,request.getUserId());
        Member member = null;
        QueryWrapper<Member> memberQueryWrapper = null;
        for(PaintingWorksModel works1:list){
            memberQueryWrapper = new QueryWrapper<>();
            memberQueryWrapper.eq("user_id",works1.getUserId());
            member = appMemberMapper.selectOne(memberQueryWrapper);
            if(member!=null){
                works1.setHeadImgUrl(member.getHeadImgUrl());
                works1.setNickName(member.getNickname());
            }
        }

        PaintingWorksModel model = null;
        PaintingWorks paintingWorks = appPaintingWorksMapper.worksDetails(request.getWorksId());
        if(paintingWorks!=null){
            model = convertWork(paintingWorks,request.getUserId());
            for(int i=0;i<list.size();i++){
                if(list.get(i).getId().equals(request.getWorksId())){
                    list.remove(i);
                }

            }
            list.add(0,model);
        }

        for(int i=0;i<list.size();i++){
            if(redisUtil.get("paymentAmount:"+list.get(i).getId())!=null){
                list.get(i).setAmount(redisUtil.get("paymentAmount:"+list.get(i).getId()).toString());
            }else{
                list.get(i).setAmount("0");
            }
        }

        response.setItems(list);
        return response;
    }

    /**
     * 作品对象转换
     * @param works
     * @return
     */
    public List<PaintingWorksModel> convertWorks(List<PaintingWorks> works){
        List<PaintingWorksModel> list = new ArrayList<>();
        PaintingWorksModel worksModel = null;
        for(PaintingWorks p:works){
            worksModel = new PaintingWorksModel();
            worksModel.setId(p.getId());
            worksModel.setUserId(p.getUserId());
            worksModel.setPainting(p.getPainting());
            worksModel.setPaintingNo(p.getPaintingNo());
            worksModel.setAllowReward(p.getAllowReward());
            worksModel.setPaintingName(p.getPaintingName());
            worksModel.setMediaTime(p.getMediaTime());
            worksModel.setVisitCount(p.getVisitCount());
            worksModel.setPraiseCount(p.getVisitCount());
            worksModel.setRewardCount(p.getRewardCount());
            worksModel.setFavourCount(p.getFavourCount());
            worksModel.setWikiId(p.getWikiId());
            worksModel.setDraftInfo(p.getDraftInfo());
            worksModel.setReshipmentCount(p.getReshipmentCount());
            worksModel.setShareCount(p.getShareCount());
            list.add(worksModel);
        }
        return list;
    }




    @Override
    public AppResponse isUpdate(AppRequest request) {
        AppResponse response = new AppResponse();
        //是否有跟新推荐
        if(redisUtil.hasKey("update:"+request.getUserId())){
            return response;
        }
        response.setCode(-1000);
        response.setMessage("暂无跟新");
        return response;
    }

    @Override
    public AppResponse resetUpdate(AppRequest request) {
        AppResponse response = new AppResponse();
        redisUtil.del("update:"+request.getUserId());
        return response;
    }


    @Override
    public AppResponse share(WorksInfoRequest request) {
        AppResponse response = new AppResponse();
        appPaintingWorksMapper.share(request.getWorksId());
        QueryWrapper<PaintingWorks> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",request.getWorksId());
        PaintingWorks paintingWorks = appPaintingWorksMapper.selectOne(queryWrapper);
        if(paintingWorks!=null){
            response.setItem(paintingWorks.getShareCount());
        }
        return response;
    }


    @Override
    public AppResponse fansRest(AppRequest request) {
        AppResponse response = new AppResponse();
        redisUtil.del("followUser:"+request.getUserId());
        return response;
    }
}
